<?php

namespace Medicina\BackendBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Medicina\KernelBundle\Entity\Concurso;
use Medicina\BackendBundle\Form\ConcursoType;
use Medicina\BackendBundle\Form\ConcursoSearchType;
use Symfony\Component\HttpFoundation\Response;

//  ejemplos de mensajes flash
// $this->get('session')->setFlash('warning', 'Concurso  se borro con exito'); equivale al info
// $this->get('session')->setFlash('notice', 'Concurso  se borro con exito');   equivale al success
// $this->get('session')->setFlash('error', 'Concurso  se borro con exito');    equivale al error
class ConcursoController extends Controller {

    public function indexAction() {
        $entity = new Concurso();
        $searchForm = $this->createForm(new ConcursoSearchType(), $entity);
        $Concursos = new \Doctrine\Common\Collections\ArrayCollection();
        $paginator = $this->get('ideup.simple_paginator');
        $em = $this->getDoctrine()->getEntityManager();
        $paginador = $this->get('ideup.simple_paginator');
        $paginador->setItemsPerPage(10);
        $request = $this->getRequest();
        $filter = false;
        if ($request->getMethod() === 'POST') {
            $searchForm->bindRequest($request);
            $searchCriteria = $searchForm->getData();
            $Concursos = $em->getRepository('MedicinaKernelBundle:Concurso')->getConcursoByCriterias($searchCriteria);
            $filter = true;
        } else {
            $Concursos = $em->getRepository('MedicinaKernelBundle:Concurso')->findAllOrderedByFechaInicio();
        }
        $entities = $paginador->paginate($Concursos)->getResult();
        $deleteForm = $this->createDeleteForm();
        return $this->render('BackendBundle:Concurso:index.html.twig', array(
                    'entities' => $entities,
                    'paginador' => $paginador,
                    'searchConcurso' => $searchForm->createView(),
                    'filter' => $filter,
                    'delete_form' => $deleteForm->createView()
                ));
    }

    public function showAction($id) {
        $permisos = $this->getPermisos();
        $em = $this->getDoctrine()->getEntityManager();
        $entity = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        if (!$entity) {
            $this->get('session')->setFlash('error', 'No se encontro el concurso!');
            return $this->redirect($this->generateUrl('concurso'));
        }
        $deleteForm = $this->createDeleteForm($id);
        $entity->getCargos()->count();
        //throw $this->createNotFoundException('mostrame la barra de depuracion!!! HDP.');        
        return $this->render('BackendBundle:Concurso:show.html.twig', array(
                    'entity' => $entity,
                    'delete_form' => $deleteForm->createView(),
                    'permisos' => $permisos
                ));
    }

    public function newAction() {
        $permisos = $this->getPermisos();
        $entity = new Concurso();
        $form = $this->createForm(new ConcursoType(), $entity, array('isNew' => true, 'permisos' => $permisos));
        return $this->render('BackendBundle:Concurso:form.html.twig', array(
                    'entity' => $entity,
                    'form' => $form->createView(),
                    'new' => true
                    , 'permisos' => $permisos
                ));
    }

    public function createAction() {
        $permisos = $this->getPermisos();
        $entity = new Concurso();
        $request = $this->getRequest();
        $form = $this->createForm(new ConcursoType(), $entity, array('isNew' => true, 'permisos' => $permisos));
        $form->bindRequest($request);
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getEntityManager();
            try {
                $user = $this->container->get('security.context')->getToken()->getUser();
                $oficina = $user->getOficina();
                //toma sensio labs , maldito DIC
                $this->setOficinaQueCarga($entity->getResoluciones(), $oficina);
                $this->setOficinaQueCarga($entity->getImpugnaciones(), $oficina);
                $em->persist($entity);
                $em->flush();
                $this->get('session')->setFlash('notice', 'Concurso   #' . $entity->getNumeroExpediente() . ' se guardo con exito');
            } catch (\PDOException $e) {
                $this->get('session')->setFlash('error', 'Error al guardar el concurso!, nro de expediente duplicado para una resolucion o una impugnacion');
                return $this->render('BackendBundle:Concurso:form.html.twig', array(
                            'entity' => $entity,
                            'form' => $form->createView(),
                            'new' => true,
                            'fails' => true,
                            'permisos' => $permisos
                        ));
            }

            return $this->redirect($this->generateUrl('concurso'));
        } else {
            $this->get('session')->setFlash('error', 'Se produjo un error');
            return $this->render('BackendBundle:Concurso:form.html.twig', array(
                        'entity' => $entity,
                        'form' => $form->createView(),
                        'new' => true,
                        'fails' => true,
                        'permisos' => $permisos
                    ));
        }
    }

    public function editAction($id) {
        $permisos = $this->getPermisos();
        $em = $this->getDoctrine()->getEntityManager();
        $entity = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        $catedraId = $entity->getCatedra()->getId();
        $estaImpugnado = $entity->estaImpugnado();
        $editForm = $this->createForm(new ConcursoType(), $entity, array('isNew' => false, 'catedraId' => $catedraId, 'permisos' => $permisos, 'estaImpugnado' => $estaImpugnado));
        $deleteForm = $this->createDeleteForm($id);

        return $this->render('BackendBundle:Concurso:form.html.twig', array(
                    'entity' => $entity,
                    'form' => $editForm->createView(),
                    'delete_form' => $deleteForm->createView(),
                    'new' => false,
                    'title' => "Editar concurso #" . $entity->getNumeroExpediente(),
                    'permisos' => $permisos,
                    'estaImpugnado' => $estaImpugnado
                ));
    }

    public function updateAction($id) {
        $permisos = $this->getPermisos();
        $asociadosOriginales = array();
        $em = $this->getDoctrine()->getEntityManager();
        $entity = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        $estaImpugnado = $entity->estaImpugnado();
        $catedraId = $entity->getCatedra()->getId();
        $this->getOriginales($entity, $asociadosOriginales);
        if (!$entity) {
            $this->get('session')->setFlash('error', 'El concurso no se encontro!');
        }
        $editForm = $this->createForm(new ConcursoType(), $entity, array('isNew' => false, 'catedraId' => $catedraId, 'permisos' => $permisos, 'estaImpugnado' => $estaImpugnado));
        $deleteForm = $this->createDeleteForm($id);
        $request = $this->getRequest();
        $editForm->bindRequest($request);
        if ($editForm->isValid()) {
            $this->unsetAsosiations($entity, $asociadosOriginales);
            $user = $this->container->get('security.context')->getToken()->getUser();
            $oficina = $user->getOficina();
            //toma sensio labs , maldito DIC
            $this->setOficinaQueCarga($entity->getResoluciones(), $oficina);
            $this->setOficinaQueCarga($entity->getImpugnaciones(), $oficina);

            //se eliminan los inscriptos que fueron puestos como ganadores para un cargo
            $this->removeGanadores($entity);

            //Se asignan las personas ganadoras una vez que esta cerrado el concurso
            if (!is_null($entity->getFechaCierre())) {
                $cargos = Array();
                $cargos = $entity->getCargos();
                $this->setInscriptosGanadores($entity, $cargos);
            }
            
            $em->persist($entity);
            $em->flush();
            
           
            
            $this->get('session')->setFlash('notice', 'Concurso guardado correctamente!');
            return $this->redirect($this->generateUrl('concurso', array('id' => $id)));
        }
//print_r($editForm->get('numeroExpediente')->getErrors());
        $this->get('session')->setFlash('error', 'Ocurrio un error al guardar el concurso!');
        return $this->render('BackendBundle:Concurso:form.html.twig', array(
                    'entity' => $entity,
                    'form' => $editForm->createView(),
                    'delete_form' => $deleteForm->createView(),
                    'new' => false,
                    'title' => "Editar concurso #" . $entity->getNumeroExpediente(),
                    'permisos' => $permisos
                ));
    }

    public function deleteAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $entity = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        if (!$entity) {
            $ $this->get('session')->setFlash('notice', 'No se encontro el concurso');
        } else {
            try {
                $expediente = $entity->getNumeroExpediente();
                $em->remove($entity);
                $em->flush();
                $this->get('session')->setFlash('notice', 'Concurso   #' . $expediente . ' se borro con exito');
            } catch (\PDOException $e) {
                $this->get('session')->setFlash('notice', 'No es posible borrar este concurso, tiene cargos ' . $entity->getCargos()->count() . ' que son usados en otros concursos ');
            }
        }
        return $this->redirect($this->generateUrl('concurso'));
    }

    protected function setInscriptosGanadores($entity, &$cargos) {
        $concursoId = $entity->getId();
        $entity->setInscriptosGanadores($concursoId, $cargos);
    }

    protected function setOficinaQueCarga($entities, $oficina) {
        foreach ($entities as $entity) {
            //expone la oficina a al objeto para ser usado por el preUpdate de doctrine
            $entity->setOficinaQueCargo($oficina);
        }
    }

    public function unsetInscriptoAction($id) {
        return $this->unsetEntity('MedicinaKernelBundle:PersonaInscripta', $id);
    }

    public function unsetAsesorAction($id) {
        return $this->unsetEntity('MedicinaKernelBundle:PersonaAsesora', $id);
    }

    public function unsetImpugnacionAction($id) {
        return $this->unsetEntity('MedicinaKernelBundle:Impugnacion', $id);
    }

    public function unsetResolucionAction($id) {
        return $this->unsetEntity('MedicinaKernelBundle:Resolucion', $id);
    }

    private function unsetEntity($entity, $id) {
        $em = $this->getDoctrine()->getEntityManager();
        $entity = $em->getRepository($entity)->find($id);
        $return = array();
        if (!$entity) {
            $this->createMsgUnset($return);
        } else {
            $em->remove($entity);
            $em->flush();
            $this->createMsgUnset($return, true);
        }
        return $this->createAjaxResponse($return);
    }

    private function createMsgUnset(&$return, $okStatus = false) {
        if ($okStatus) {
            $return['status'] = true;
            $return['mensaje'] = "Borrado con exito";
        } else {
            $return['status'] = false;
            $return['mensaje'] = "Ocurrio un error al intentar borrar";
        }
        return $return;
    }

    private function createAjaxResponse($return) {
        return new Response(json_encode($return), 200, array('Content-Type' => 'application/json'));
    }

    private function createDeleteForm() {
        return $this->createFormBuilder()->getForm();
    }

    protected function unsetAsosiations($object, &$asociadosOriginales) {
        $this->removeInscriptos($object, $asociadosOriginales['inscriptos']);
        $this->removeAsesores($object, $asociadosOriginales['asesores']);
        $this->removeImpugnaciones($object, $asociadosOriginales['ipmugnaciones']);
        $this->removeResoluciones($object, $asociadosOriginales['resoluciones']);
    }

    protected function removeInscriptos($object, &$originalInscriptos = array()) {
        $this->removeElements($object->getInscriptos(), $originalInscriptos);
    }

    protected function removeAsesores($object, &$originalAsesores = array()) {
        $this->removeElements($object->getAsesores(), $originalAsesores);
    }

    protected function removeImpugnaciones($object, &$originalImpugnaciones = array()) {
        $this->removeElements($object->getImpugnaciones(), $originalImpugnaciones);
    }

    protected function removeResoluciones($object, &$originalResoluciones = array()) {
        $this->removeElements($object->getResoluciones(), $originalResoluciones);
    }

    protected function removeGanadores($object) {
        $concursoId = $object->getId();
        $em = $this->getDoctrine()->getEntityManager();
        $em->getRepository('MedicinaKernelBundle:Concurso')->deleteByConcurso($concursoId);
    }

    protected function getOriginales($object, &$asociadosOriginales) {
        $originalInscriptos = array();
        $originalAsesores = array();
        $originalImpugnaciones = array();
        $originalResoluciones = array();

        foreach ($object->getInscriptos() as $inscripto)
            $originalInscriptos[] = $inscripto;
        foreach ($object->getAsesores() as $asesor)
            $originalAsesores[] = $asesor;
        foreach ($object->getImpugnaciones() as $impugnacion)
            $originalImpugnaciones[] = $impugnacion;
        foreach ($object->getResoluciones() as $resolucion)
            $originalResoluciones[] = $resolucion;

        $asociadosOriginales['inscriptos'] = $originalInscriptos;
        $asociadosOriginales['asesores'] = $originalAsesores;
        $asociadosOriginales['ipmugnaciones'] = $originalImpugnaciones;
        $asociadosOriginales['resoluciones'] = $originalResoluciones;
    }

    protected function removeElements($elements, &$original = array()) {
        foreach ($elements as $el) {
            foreach ($original as $key => $toDel) {
                if ($toDel->getId() === $el->getId()) {
                    unset($original[$key]);
                }
            }
        }
        // Elimina la relacion entre el concurso  y la PersonaInscripta
        foreach ($original as $el) {
            $em = $this->getDoctrine()->getEntityManager();
            $em->remove($el);
        }
    }

    public function cargosCatedraAction($id) {
        $permisos = $this->getPermisos();
        $entity = new Concurso();
        $em = $this->getDoctrine()->getEntityManager();
        $form = $this->createForm(new ConcursoType(), $entity, array('isCargoAjax' => true, 'catedraId' => $id, 'permisos' => $permisos));
        return $this->render('BackendBundle:Concurso:cargosForm.html.twig', array(
                    'entity' => $entity,
                    'form' => $form->createView(),
                    'permisos' => $permisos
                ));
    }

    public function getByCatedraAction($catedraId) {
        $entity = new Concurso();
        $searchForm = $this->createForm(new ConcursoSearchType());
        $Concursos = new \Doctrine\Common\Collections\ArrayCollection();
        $filter = false;
        $session = $this->get('session');
        $session->set('s_isSearch', false);
        $em = $this->getDoctrine()->getEntityManager();
        $paginador = $this->get('ideup.simple_paginator');
        $paginador->setItemsPerPage(10);
        $request = $this->getRequest();
        $searchForm->bindRequest($request);
        $Concursos = $em->getRepository('MedicinaKernelBundle:Concurso')->concursosParaCatedra($catedraId);
        $catedra = $em->getRepository('MedicinaKernelBundle:Catedra')->find($catedraId);
        $entities = $paginador->paginate($Concursos)->getResult();
        $deleteForm = $this->createDeleteForm();
        return $this->render('BackendBundle:Concurso:index.html.twig', array(
                    'entities' => $entities,
                    'paginador' => $paginador,
                    'searchConcurso' => $searchForm->createView(),
                    'filter' => $filter,
                    'delete_form' => $deleteForm->createView(),
                    'title' => "Listado de concursos asociados a catedra " . $catedra->getNombre()
                ));
    }

    public function getByTipodecargoAction($tipodecargoId) {
        $entity = new Concurso();
        $searchForm = $this->createForm(new ConcursoSearchType());
        $Concursos = new \Doctrine\Common\Collections\ArrayCollection();
        $filter = false;
        $session = $this->get('session');
        $session->set('s_isSearch', false);
        $em = $this->getDoctrine()->getEntityManager();
        $paginador = $this->get('ideup.simple_paginator');
        $paginador->setItemsPerPage(10);
        $request = $this->getRequest();
        $searchForm->bindRequest($request);
        $Concursos = $em->getRepository('MedicinaKernelBundle:Concurso')->concursosParaTipodecargo($tipodecargoId);
        $tipodecargo = $em->getRepository('MedicinaKernelBundle:Tipodecargo')->find($tipodecargoId);
        $entities = $paginador->paginate($Concursos)->getResult();
        $deleteForm = $this->createDeleteForm();
        return $this->render('BackendBundle:Concurso:index.html.twig', array(
                    'entities' => $entities,
                    'paginador' => $paginador,
                    'searchConcurso' => $searchForm->createView(),
                    'filter' => $filter,
                    'delete_form' => $deleteForm->createView(),
                    'title' => "Listado de concursos asociados a tipo de cargo " . $tipodecargo->getNombre()
                ));
    }

    public function inscriptosAceptadosAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $results = $em->getRepository('MedicinaKernelBundle:Concurso')->inscriptosAceptados($id);
        return $this->getInscriptosResponse($results, 'concurso_inscriptos_aceptados', 'Inscriptos  Aceptados', $id);
    }

    public function inscriptosRechazadosAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $results = $em->getRepository('MedicinaKernelBundle:Concurso')->inscriptosRechazados($id);
        return $this->getInscriptosResponse($results, 'concurso_inscriptos_rechazados', 'Inscriptos Rechazados', $id);
    }

    public function inscriptosGanadoresAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $results = $em->getRepository('MedicinaKernelBundle:Concurso')->inscriptosGanadores($id);
        return $this->getInscriptosResponse($results, 'concurso_inscriptos_ganadores', 'Inscriptos Ganadores', $id);
    }

    protected function getInscriptosResponse($results, $rutaPaginador, $title, $id) {
        $paginador = $this->get('ideup.simple_paginator');
        $paginador->setItemsPerPage(10);
        $em = $this->getDoctrine()->getEntityManager();
        $concurso = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        $entities = $paginador->paginate($results)->getResult();
        $title = $title . " para el  concurso con expediente " . $concurso->getNumeroExpediente();
        if ($concurso->estaImpugnado()) {
            $title = $title . " estado impugnado";
        }
        if (empty($entities)) {
            $title = "No tiene " . $title;
        }
        return $this->render('BackendBundle:Concurso:showMoreInscriptos.html.twig', array(
                    'entities' => $entities,
                    'paginador' => $paginador,
                    'title' => $title,
                    'rutaPaginador' => $rutaPaginador,
                    'concurso' => $id,
                    'esEditor' => true,
                    'permisos' => $this->getPermisos(),
                    'estaImpugnado' => $concurso->estaImpugnado(),
                    'estaCerrado' => $concurso->getCerrado()
                ));
    }

    public function cargoGetInfoAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $cargo = $em->getRepository('MedicinaKernelBundle:Cargo')->find($id);
        return $this->render('BackendBundle:Concurso:cargoMoreInfo.html.twig', array(
                    'cargo' => $cargo
                ));
    }

    public function getOficinasPasoAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $concurso = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        return $this->render('BackendBundle:Concurso:oficinasQueEstuvo.html.twig', array(
                    'entity' => $concurso
                ));
    }

    public function getAsesoresAction($id) {
        $em = $this->getDoctrine()->getEntityManager();
        $results = $em->getRepository('MedicinaKernelBundle:Concurso')->getAllAsesores($id);
        $concurso = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        $tipoAsesor = new \Medicina\KernelBundle\Entity\PersonaAsesora();
        $form = $this->createForm(new \Medicina\BackendBundle\Form\TipoAsesorType(), $tipoAsesor);
        $paginador = $this->get('ideup.simple_paginator');
        $paginador->setItemsPerPage(10);
        $entities = $paginador->paginate($results)->getResult();
        $title = "Listado de Asesores para el  concurso con expediente" . $concurso->getNumeroExpediente();
        if ($concurso->estaImpugnado()) {
            $title = $title . " estado impugnado";
        }
        if (empty($entities)) {
            $title = "No tiene Asesores  el  concurso con expediente" . $concurso->getNumeroExpediente();
        }
        return $this->render('BackendBundle:Concurso:asesoresListado.html.twig', array(
                    'entities' => $entities,
                    'paginador' => $paginador,
                    'title' => $title,
                    'rutaPaginador' => "concurso_get_asesores",
                    'concurso' => $id,
                    'form' => $form->createView(),
                    'permisos' => $this->getPermisos(),
                    'estaImpugnado' => $concurso->estaImpugnado(),
                    'estaCerrado' => $concurso->getCerrado()
                ));
    }

    public function openAction($id) {
        $output = array();
        $em = $this->getDoctrine()->getEntityManager();
        $concurso = $em->getRepository('MedicinaKernelBundle:Concurso')->find($id);
        if (!$concurso) {
            $output['msg'] = 'No encontro el concurso';
            $output['status'] = false;
        } else {
            try {
                $expediente = $concurso->getNumeroExpediente();
                $concurso->setCerrado(false);
                $em->flush();
                $output['msg'] = 'Concurso   #' . $expediente . ' se reabrio con exito';
                $output['status'] = true;
            } catch (\PDOException $e) {
                $output['msg'] = 'No es posible reabrir el concurso, error al intentar hacerlo';
                $output['status'] = false;
            }
        }
        return new Response(json_encode($output), 200, array('Content-Type' => 'application/json'));
    }

    function getPermisos() {

        /*
          (1, 'ROLE_SUPER_ADMIN'),
          (2, 'ROLE_ADMIN'),
          (3, 'ROLE_USUARIO'),
          (4, 'ROLE_PERSONAL'),
          (5, 'ROLE_PROFESORADO'),
          (6, 'ROLE_DESPACHO'),
          (7, 'ROLE_CONS_DIRECTIVO'),
          (8, 'ROLE_EDITAR_INSCRIPTO'),
          (9, 'ROLE_EDITAR_ASESOR'),
          (10, 'ROLE_EDITAR_RESOLUCION'),
          (11, 'ROLE_EDITAR_IMPUGNACION' ); */
        $permisos = array(
            'puedeTodo' => false
            , 'general' => false
            , 'impugnaciones' => false
            , 'inscriptos' => false
            , 'asesores' => false
            , 'resoluciones' => false
            , "botoneraConcurso" => false
        );
        $user = $this->container->get('security.context')->getToken()->getUser();
        $inRoles = $user->getRoles();
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN'), $inRoles)) {
            $permisos['puedeTodo'] = true;
        }
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_PERSONAL'), $inRoles)) {
            $permisos['general'] = true;
        }
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_EDITAR_IMPUGNACION'), $inRoles)) {
            $permisos['impugnaciones'] = true;
        }
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_EDITAR_INSCRIPTO'), $inRoles)) {
            $permisos['inscriptos'] = true;
        }
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_EDITAR_ASESOR'), $inRoles)) {
            $permisos['asesores'] = true;
        }
        if ($this->incluye(array('ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_EDITAR_RESOLUCION'), $inRoles)) {
            $permisos['resoluciones'] = true;
        }

        return $permisos;
    }

    private function incluye($haystack, $target) {
        $output = false;
        if (count(array_intersect($haystack, $target)) > 0) {
            //at least one of $target is in $haystack
            $output = true;
        }

        if (count(array_intersect($haystack, $target)) == count($target)) {
            // all of $target is in $haystack
        }
        return $output;
    }

    public function checkCargosAction($concurso, $values) {
        $em = $this->getDoctrine()->getEntityManager();
        $cargos = $em->getRepository('MedicinaKernelBundle:Concurso')->checkCargos($concurso, $values);

        //  print_r($cargos);
//        return $this->render('BackendBundle:Concurso:output.html.twig', array(
//                    'cargos' => $cargos
//                ));
//        
        $ouput = array();
        $ouput['cargos'] = $cargos;
        return new Response(json_encode($ouput), 200, array('Content-Type' => 'application/json'));
    }

}
